#define GPFSEL1		0x20200004U
#define GPCLR0		0x20200028U
#define GPSET0		0x2020001CU

#define IRQ_BASIC_PENDING	0x2000B200U
#define IRQ_PENDING_1		0x2000B204U
#define IRQ_PENDING_2		0x2000B208U
#define FIQ_CONTROL			0x2000B20CU
#define ENABLE_IRQ_1		0x2000B210U
#define ENABLE_IRQ_2		0x2000B214U
#define ENABLE_BASIC_IRQ	0x2000B218U
#define DISABLE_IRQ_1		0x2000B21CU
#define DISABLE_IRQ_2		0x2000B220U
#define DISABLE_BASIC_IRQ	0x2000B224U

#define ARM_TIMER_LOAD		0x2000B400U
#define ARM_TIMER_VALUE		0x2000B404U	// READ ONLY
#define ARM_TIMER_CONTROL	0x2000B408U
#define ARM_TIMER_IRQ_ACK	0x2000B40CU	// WRITE ONLY
#define ARM_TIMER_RAW_IRQ	0x2000B410U // READ ONLY
#define ARM_TIMER_MASK_IRQ	0x2000B414U	// READ ONLY
#define ARM_TIMER_RELOAD	0x2000B418U
#define ARM_TIMER_PREDIV	0x2000B41CU
#define ARM_TIMER_FRC		0x2000B420U


extern void Set32(unsigned int addr, unsigned int value);
extern unsigned int Get32(unsigned int addr);
extern void EnableIRQ(void);
extern void ThrowSWI(void);


/**************************************************
 * Gestion de la LED
 **************************************************/

unsigned int ledStatus = 0U;

void TurnLedOn(void)
{
	// On allume la led
	unsigned int *gpclr0_ptr = ((unsigned int*)GPCLR0);
	*gpclr0_ptr = *gpclr0_ptr | 0x10000U;
	ledStatus++;
}

void TurnLedOff(void)
{
	// On éteint la led
	unsigned int *gpclr0_ptr = ((unsigned int*)GPSET0);
	*gpclr0_ptr = *gpclr0_ptr | 0x10000U;
	ledStatus++;
}

void SwitchLed(void)
{
	if ((ledStatus & 1U) == 0U)
	{
		TurnLedOff();
	}
	else
	{
		TurnLedOn();
	}
}

void InitLed(void)
{
	// On active la fonction du 1 du pin 16 du GPIO
	unsigned int *gpfsel1_ptr = ((unsigned int*)GPFSEL1);
	*gpfsel1_ptr = *gpfsel1_ptr | 0x40000U;
	TurnLedOff();
}


/*******************************************************
* Géstion des SWI
* ******************************************************/
void SWIHandler(void)
{
	TurnLedOn();
}


/*****************************************************
 * Fonction kmain
 *****************************************************/
int kmain(void)
{
	// On intialise la LED
	InitLed();

	//On active les IT
	EnableIRQ();

	ThrowSWI();

	for ( ;; )
	{
		// RAF
	}

	return 0;
}
